﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using Caliburn.Micro.BikeWizard.Services;
using Caliburn.Micro.BikeWizard.Data;

namespace Caliburn.Micro.BikeWizard.Views
{
    public class OptionViewModel<TValue> : PropertyChangedBase,
        IComparable<OptionViewModel<TValue>>
    {
        #region Fields
        private const int UNSET_SORT_VALUE = Int32.MinValue;
        private readonly string displayName;
        private bool isSelected;
        private readonly int sortValue;
        private readonly TValue value;
        #endregion

        #region Constructors
        public OptionViewModel(string displayName, TValue value)
            : this(displayName, value, UNSET_SORT_VALUE)
        {
        }

        public OptionViewModel(string displayName, TValue value, int sortValue)
        {
            this.displayName = displayName;
            this.value = value;
            this.sortValue = sortValue;
        }
        #endregion

        #region Properties
        /// <summary>
        /// Returns the user-friendly name of this option.
        /// </summary>
        public string DisplayName
        {
            get { return displayName; }
        }

        /// <summary>
        /// Gets/sets whether this option is in the selected state.
        /// When this property is set to a new value, this object's
        /// PropertyChanged event is raised.
        /// </summary>
        public bool IsSelected
        {
            get { return isSelected; }
            set
            {
                if (value == isSelected)
                    return;

                isSelected = value;
                NotifyOfPropertyChange(() => IsSelected);
            }
        }

        /// <summary>
        /// Returns the value used to sort this option.
        /// The default sort value is Int32.MinValue.
        /// </summary>
        public int SortValue
        {
            get { return sortValue; }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Returns the underlying value of this option.
        /// Note: this is a method, instead of a property,
        /// so that the UI cannot bind to it.
        /// </summary>
        internal TValue GetValue()
        {
            return value;
        }
        #endregion

        #region IComparable<OptionViewModel<TValue>> Members
        public int CompareTo(OptionViewModel<TValue> other)
        {
            if (other == null)
                return -1;

            if (this.SortValue == UNSET_SORT_VALUE && other.SortValue == UNSET_SORT_VALUE)
            {
                return this.DisplayName.CompareTo(other.DisplayName);
            }
            else if (this.SortValue != UNSET_SORT_VALUE && other.SortValue != UNSET_SORT_VALUE)
            {
                return this.SortValue.CompareTo(other.SortValue);
            }
            else if (this.SortValue != UNSET_SORT_VALUE && other.SortValue == UNSET_SORT_VALUE)
            {
                return -1;
            }
            else
            {
                return +1;
            }
        }
        #endregion
    }
}
